home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 25 / Cream of the Crop 25.iso / os2 / srefv12i.zip / postfchk.rxx < prev    next >
Text File  |  1997-04-08  |  28KB  |  960 lines

  1. /* Recording and postfilter module for sre-filter */
  2.  
  3. /* Some comments on the "record_all_file" cache algorithim:
  4.    To speed up performance, SRE-Filter caches all writes
  5.    to the record_all_file.  This saves disk i/o (and repetitive
  6.    parsing of the entries).
  7.  
  8.    There are a few points worth considering in regards to this caching:
  9.       1) More memory is required to store the cache.  One
  10.          can limit the size of the cache by changing the record_cache_lines
  11.          variable, with smaller values yielding smaller caches.
  12.          For example, the default value of 1000 means "1000 entries".
  13.          At an average size of 50 bytes, that's around
  14.          5000 bytes total storage.
  15.  
  16.       2) If you have a lot of files being requested, with each having
  17.          their own entry  (that is, few if any wildcards), you may fill up
  18.          this cache. When this happens, SRE-Filter will write the
  19.          current cache to an archive file (with name .1 to .999),
  20.          and reset all values. "Reset" means:
  21.                 a) Set "counter" values on wildcards to 0
  22.                 b) Remove non-wildcard entries
  23.         Of course, this new file could also fill up quickly, yielding
  24.         a multiplicity of archive files.
  25.         Should this happen, you should probably increase the size of the cache.
  26.  
  27.       3) As a safety measure, the cache will be written to the record_all_file
  28.          every 5 minutes. When doing this, the current record_all_file
  29.          is given the name .bak (overwriting a preexisting .bak file).
  30.  
  31.       4) If you should change the record_all_file by hand (you add
  32.          a wildcard entry), SRE-Filter will detect the change and
  33.          re-read the file into the cache.  This will ERASE
  34.          all "recorded in cache but not written to file" entries --
  35.          that is, everything in the (up to) last 5 minutes.
  36.          If this minor inaccuracy (assuming that adding entries to
  37.          the Record_all_file is a rare event) can be avoided by:
  38.                 1) Turning off caching (set RECORD_CACHE_LINES=0)
  39.                 2) Setting a very fast update rate (set UPDATE_RATE=0.2,
  40.                    see below for details)
  41.                 3) Issue a !WRITE_CACHE request just prior to editing
  42.                    the record_all_file (though this any changes that
  43.                    occur whilst editing the file will be missed).
  44.          Only method #1 is guaranteed to work, but it also is the slowest.
  45.          Then again, absolute accuracy in this type of general audit
  46.          file is usually not a priority (you should use SENDFILE
  47.          for greater precision)
  48.  
  49.      5) When writing the cache, SRE-Filter will
  50.            a)put ALL comments at the top
  51.            b)write the list of "wildcard entries" (if any)
  52.            c)write the "non-wildcard entries" (if any)
  53.         Thus, placements of comments in between entries will be
  54.         lost (sorry, if that's really a problem contact us
  55.         and we'll consider keeping track of placement so as
  56.         to preserve order on writes).
  57.  
  58.         In fact, the most frequent "non-wildcard" entries will
  59.         be written first!
  60.  
  61.       6) If active, the HIT_CACHE will be examined before
  62.          recording an entry.
  63.  
  64. */
  65.  
  66. /* -----------------------------------------*/
  67. /* Some user configurable parameters -- you have to restart goserve
  68. for them to take effect*/
  69.  
  70. /* enter frequency, in minutes, for writing cache to file (0.2 < x < 60)
  71. Note: to suppress caching, set record_cache_lines=0 in srefiltr.80
  72. */
  73. update_rate=5
  74.  
  75.  
  76. /* enter lazy_write time for common log cache, in seconds */
  77. lazy_clog=22
  78.  
  79.  
  80. /* warn (via pmprintf) when log file gets over this size (in kbytes) */
  81. /* to suppress this check, set log_toobig=0 (not checking saves a little bit of time)*/
  82. log_toobig=1000
  83.  
  84.  
  85. /* ---- Do NOT change code below here ---------------------------*/
  86.  
  87. parse upper arg   usequeue , USESEM,max_semwait, stuff
  88. parse var stuff record_cache_lines workdir
  89. workdir=strip(workdir,'t','\')
  90.  
  91. call pmprintf(' SRE-FILTER postfilter thread: queue='||usequeue)
  92. call pmprintf(' SRE-FILTER postfilter thread: semaphore='||usesem)
  93.  
  94. mytid=dostid()
  95. call pmprintf(' SRE-FILTER postfilter thread: thread id='||mytid)
  96.  
  97. if  usequeue="" | USESEM="" then do
  98.    call pmprintf('SRE-FILTER postfilter thread: initialization ERROR: '||accessfile||','||usequeue)
  99.    exit
  100. end
  101.  
  102. signal on error name iserror
  103. signal on syntax name iserror
  104.  
  105. comments.filestamp=0
  106. if datatype(update_rate)<>'NUM' then update_rate=5
  107. update_rate=max(min(update_rate,60),0.2)
  108. update_rate=update_rate/(24*60)
  109.  
  110. if datatype(lazy_clog)<>'NUM' then lazy_clog=30
  111. if lazy_clog>1000 then lazy_clog=1000   /* in case some on messes up */
  112.  
  113. if datatype(log_toobig)<>'NUM' then log_toobig=1000
  114.  
  115. /* get sreflogs.ini from workdir */
  116. afl=workdir||'\SREFLOGS.INI'
  117. logini=stream(afl,'c','query exists')
  118. call pmprintf(' SRE-FILTER postfilter thread: common-log configuration file='logini)
  119. foo=GET_sreflogs()
  120. blog.0=0; clog.0=0 ; rlog.0=0
  121. lasttime=time('s') ; THISTIME=LASTTIME
  122. do_write_cache=0
  123.  
  124. /* loop forevvefeerrrererere ...... */
  125. bakme:
  126.  
  127.  thistime=time('s')
  128. /* write common log, and perhaps update the .ini file */
  129.  if abs(thistime-lasttime)>lazy_clog  | do_wRITE_CACHE=1 then do
  130.        do_write_cache=0
  131.        foo=write_clog(thistime,lasttime,log_toobig)
  132.        foo=write_blog()
  133.        foo=write_rlog()
  134.        if (write_logs<>0) & ( (verbose>2 & clog.0>0) | verbose>3 |  (abbrev(upper(seloriginal),'!WRITE_CACHE')=1) ) then
  135.           call pmprintf(' Writing common-log entries: 'clog.0','blog.0','rlog.0)
  136.        ostamp=sysfiletree(logini,'FOO','F');OSTAMP=FOO.1
  137.        if  ostamp<>stuff.!stamp then do
  138.          if verbose>1 then call pmprintf(' SRE-FILTER postfilter thread: updating 'logini)
  139.          foo=GET_sreflogs()
  140.        end
  141.  
  142.        lasttime=thistime
  143.        blog.0=0; clog.0=0 ; rlog.0=0
  144.  end
  145.  
  146.  a=rxqueue('s',usequeue)
  147.  goo=queued()
  148.  if goo=0 then do
  149.     WOW=EVENTSEM_WAIT(USESEM,max_semwait)
  150.  
  151.     if wow=640 then do
  152.         signal bakme
  153.     end
  154.     IF WOW<>0 THEN do         /* FATAL ERROR */
  155.         EXIT
  156.     end
  157.  end
  158.  wow=EVENTSEM_RESET(usesem)
  159.  if queued()<1 then signal bakme
  160.  parse pull isit0
  161.  isit0=translate(isit0,' ','000d0a09'x)
  162.  
  163.  if isit0=" " then signal bakme
  164.  
  165.  if abbrev(strip(translate(isit0)),'*DIE*')=1 then do
  166.      call pmprintf('SRE-FILTER postfilter thread: terminating ')
  167.      exit
  168.  end
  169.  if isit0="" then do
  170.       call pmprintf('SRE-FILTER postfilter thread: bad message ')
  171.      signal bakme
  172. end
  173.  
  174. parse var isit0 record_option ',' record_all_file ',' post_filter ',' postfilter_name ',' serverport ',' ,
  175.                  post_filter_message ',' source0 ',' request0a ',' ,
  176.                sel0 ',' tempfile ','  servername ',' host_nickname ',' used_file ',' who  ',' ,
  177.                enmadd ',' thereferer ',' tcache ',' REcord2 ',' write_logs ',' clientname0 ',' user ','  browser ',' verbose
  178.  
  179. parse var record2 record_status record_bytes
  180. write_logs=strip(write_logs) ; clientname0=upper(strip(clientname0))
  181. browser=strip(browser) ; user=strip(user)
  182. if user=' ' then user='-'
  183. verbose=strip(verbose)
  184.  
  185.  record_option=strip(record_option) ; post_filter=strip(post_filter)
  186.  postfilter_name=strip(postfilter_name) ; record_all_file=strip(record_all_file)
  187. serverport=strip(serverport) ; servername=strip(servername)
  188. host_Nickname=strip(Host_nickname) ; used_file=strip(used_file)
  189. parse var sel0 doorig sel0
  190. seloriginal=packur(strip(sel0)) 
  191.  
  192. who=strip(who)
  193. request0=packur(strip(request0a));
  194. post_filter_message=packur(post_filter_message)
  195. enmadd=strip(enmadd) ; tcache=strip(tcache)
  196. thereferer=strip(thereferer)
  197.  
  198. parse var seloriginal doit '?' .
  199.  
  200. if abbrev(upper(seloriginal),'!WRITE_CACHE')=1 then do_write_cache=1
  201.  
  202.  
  203.  if record_option<>"NO" then do
  204.      select
  205.         when record_option="YES" then
  206.                 parse var seloriginal doit '?' .
  207.         when record_option='YES_ALL' then
  208.                 doit=seloriginal
  209.         otherwise                       /* file */
  210.               doit=used_File
  211.      end
  212.  
  213.      doit=strip(strip(doit),'l','/')
  214.      if host_Nickname<>"" & record_option<>'FILE' then
  215.                doit=host_Nickname'//'doit
  216.       njust=' '
  217.       if do_write_cache<>1 then   njust=sref_look_hit_cache('P',doit,who,enmadd)
  218.  
  219.       if njust=' ' then do      /* not in cache, so record */
  220.          zfoo=0                   /* do we use a recordall file cache? */
  221.          if record_cache_lines>0 then do
  222.             zfoo=do_cache_record(record_all_file,doit,seloriginal)
  223.          end
  224.          if zfoo=0 then do
  225.              foo=sref_lookup_count(record_all_file,doit,'ADD','OK',2)
  226.          end
  227.          foo=sref_add_hit_cache("P",doit,who,enmadd,zfoo)
  228.       end               /* not just hit */
  229.   end                   /* record option */
  230.  
  231. /* log this one (uses stuff. */
  232.  iik=is_logok(seloriginal,doorig,clientname0,record_status,write_logs,user)
  233.  if iik=1 then do               /* write to the common log file */
  234.       d1=space(strip(date('n'))); 
  235.       parse var d1 d1a d1b d1c
  236.       if d1a<10 then d1a='0'||d1a
  237.       d1=d1a||'/'||d1b||'/'||d1c
  238.       t1=time('n')
  239.       d1t1=d1||':'||t1
  240.       agmt=gmtoffset()
  241.       if datatype(agmt)='NUM' then do
  242.          agmt=agmt/36
  243.          if abs(agmt)<1000 then do
  244.              if agmt>0 then
  245.                  agmt='0'||agmt
  246.              else
  247.                  agmt='-0'||abs(agmt)
  248.          end
  249.       end
  250.       d1t1=d1t1||' '||agmt
  251.       parse var request0 mkme a2a a3
  252.       thereq=strip(a2a)
  253.       if stuff.!nooptions=1 then parse var thereq thereq '?' .
  254.       mkme=mkme||' '||thereq
  255.       if stuff.!nohttp=0 then mkme=mkme||' '||a3
  256.       d1t1='['||d1t1||']'
  257.  
  258. /* this is the output to the common-log file */
  259.       ii=clog.0+1
  260.       clogq=clientname0||' - '||user||' '||d1t1||' "'||mkme||'" '||strip(record2)
  261.       clog.ii=clogq
  262.       clog.ii.!file=which_logs(serverport,host_nickname,'COMMONLOG')
  263.       clog.0=ii
  264.  
  265. /* the browser log */
  266.       ii=blog.0+1
  267.       blog.ii.!file=which_logs(serverport,host_nickname,'BROWSERLOG')
  268.       blog.ii=d1t1||' '||clientname0||' '||browser
  269.       blog.0=ii
  270.  
  271. /* the referer log */
  272.       if thereferer<>" " then do
  273.           parse var thereferer . '//' refip '/' .
  274.           iik=is_logok(-1,,refip)
  275.           if iik=1 then do
  276.              ii=rlog.0+1
  277.              rlog.ii=d1t1||' "'||thereq||'" '||thereferer
  278.              rlog.ii.!file=which_logs(serverport,host_nickname,'REFERERLOG')
  279.              rlog.0=ii
  280.           end
  281.       end
  282.  
  283.      if verbose>0 then call pmprintf(left(clogq,120))
  284.  
  285.   end
  286.  
  287.  IF POST_FILTER="NO" | post_filter=0 THEN do
  288.     if tcache<>' ' then foo=sysfiledelete(tcache)
  289.     signal bakme
  290.   end
  291.  
  292.  tookie=postfilter_name
  293.  do mm=1 to words(tookie)
  294.    postfilter_name=word(tookie,mm)
  295.    if pos('.',postfilter_name)=0 then
  296.         postfilter_name=postfilter_name||'.'||serverport
  297.  
  298.    signal on syntax name bad2
  299.    signal on error name bad2
  300.     yow='foo3='||postfilter_name||'(post_filter_message,source0,request0a,sel0,tempfile,servername,HOST_NICKNAME,used_file,thereferer,tcache,record2)'
  301.  
  302.    interpret yow
  303.  
  304.    signal off syntax;  signal off error
  305.  end
  306.  
  307.  if tcache<>' ' then foo=sysfiledelete(tcache)
  308.  signal bakme
  309.  
  310. bad2:
  311.   signal off syntax; signal off error
  312.   call pmprintf(" SRE-Filter Postfilter Thread: Problem in post_filter routine " postfilter_name " ("seloriginal)
  313.   if tcache<>' ' then foo=sysfiledelete(tcache)
  314.   signal bakme
  315.  
  316.  
  317. iserror:
  318. signal off error ; signal off syntax
  319. call pmprintf(' error in postfilter : resetting 'sigl)
  320. a=rxqueue('d',usequeue)
  321. a=rxqueue('c',usequeue)
  322. a=eventsem_close(usesem)
  323. a=eventsem_create(usesem)
  324. call pmprintf(' done resetting postfilter ')
  325. signal on error name iserror
  326. signal on syntax name iserror
  327. signal bakme
  328.  
  329.  
  330. /* ========================================================== */
  331. /* --- handle "cached recordall_file -----*/
  332. do_cache_record:procedure expose record_cache_lines wilds. comments. simples. ,
  333.                 update_rate verbose
  334.  
  335. parse arg record_all_file,doit,doit0
  336.  
  337. numeric digits 15
  338.  
  339. /* no cache -- then get one */
  340. if comments.filestamp=0 then do
  341.     nrecs=open_record_cache(record_all_file)
  342.    if verbose>0 then call pmprintf(" First read of RECORD_ALL_FILE: " nrecs)
  343.     if nrecs=0 then return 0
  344. end
  345. else do
  346.     nrecs=comments.0+simples.0+wilds.0
  347. end  /* Do */
  348.  
  349. /* cache too big? */
  350. if nrecs>record_cache_lines then do
  351.     nrecs=reset_cache(record_all_file,record_cache_lines)
  352. end
  353.  
  354. /* add current hit,  or re-read file  */
  355. foo=update_cache(doit)
  356.  
  357. /* do a timed updated to disk */
  358. d1=date('b')
  359. t1=time('s')/(24*60*60)
  360. nowtime=d1+t1
  361. yeeks=comments.istime+update_rate
  362. if (yeeks<nowtime) | strip(upper(doit0))="!WRITE_CACHE" then do
  363.    foo=save_cache(record_all_file)
  364. end
  365.  
  366.  
  367. return 1
  368.  
  369.  
  370. /* ---------------- read recordall file into cache */
  371. open_record_cache:procedure expose wilds. comments. simples. verbose
  372. parse arg record_all_file
  373.  
  374. aa=fileread(record_all_file,thelines,,'E')
  375. if aa<0 then return 0                /* error, use default method */
  376.  
  377. drop wilds. comments. simples.
  378.  
  379. nsimples=0 ; ncomments=0 ; nwilds=0
  380. simples.0=0 ; comments.0=0 ; wilds.0=0
  381. do mm=1 to thelines.0
  382.    aline=strip(thelines.mm)
  383.    if abbrev(aline,';')=1 | aline=' '  then do
  384.         if aline=' ' then iterate
  385.         ncomments=ncomments+1
  386.         comments.ncomments=aline
  387.         comments.0=ncomments
  388.    end
  389.    else do
  390.        parse  var aline aname act amess
  391.        if pos('*',aname)>0 then do
  392.            aname=strip(aname)
  393.            aname=translate(aname,'/','\')
  394.            aname=strip(aname,'l','/')
  395.            if act="" | datatype(act)<>'NUM' then act=0
  396.            nwilds=nwilds+1
  397.            wilds.nwilds.qname=aname ; wilds.nwilds.qct=act
  398.            wilds.nwilds.qmess=amess
  399.            wilds.0=nwilds
  400.        end
  401.        else do
  402.             nsimples=nsimples+1
  403.             if act="" | datatype(act)<>'NUM' then act=0
  404.             simples.nsimples.qname=aname; simples.nsimples.qct=act
  405.             simples.nsimples.qmess=amess
  406.             simples.0=nsimples
  407.        end
  408.    end
  409. end
  410.  
  411. /* get time stamp */
  412. d1=date('b')
  413. t1=time('s')/(24*60*60)
  414. comments.istime=d1+t1
  415.  
  416. /* get file stamp */
  417. oo=sysfiletree(record_all_file,'yow')
  418. comments.filestamp=strip(upper(yow.1))
  419.  
  420.  
  421. return nwilds+ncomments+nsimples
  422.  
  423.  
  424. /* ------------------- Write cache---------------*/
  425. write_cache:procedure expose comments. wilds. simples. verbose
  426. parse arg rfile,addtimestamp
  427.  
  428.  
  429. nj=0
  430. if addtimestamp=1 then do
  431.    nj=1
  432.    alines.nj="; File reset on: "||time('N')||' '||date('N')
  433. end  /* Do */
  434.  
  435. do mm=1 to comments.0
  436.   nj=nj+1
  437.   alines.nj=comments.mm
  438. end
  439. do mm=1 to wilds.0
  440.   nj=nj+1
  441.   alines.nj=wilds.mm.qname||' '||wilds.mm.qct||' '||wilds.mm.qmess
  442. end
  443.  
  444.  
  445. /* sort simples in descending order, by frequency */
  446. do iy=1 to simples.0
  447.    foobar.iy=simples.iy.qct'         'iy
  448. end
  449. if simples.0>0 then wow=arraysort(foobar,1,simples.0,1,8,'D','N')
  450.  
  451. do mm=1 to simples.0
  452.     parse var foobar.mm act indx ; indx=strip(indx)
  453.     nj=nj+1
  454.     alines.nj=simples.indx.qname||' '||simples.indx.qct||' '||simples.indx.qmess
  455. end
  456.  
  457. alines.0=nj
  458.  
  459.  
  460.  
  461. wow=filewrite(rfile,alines)
  462.  
  463. /* get time stamp */
  464. d1=date('b')
  465. t1=time('s')/(24*60*60)
  466. comments.istime=d1+t1
  467.  
  468. /* get file stamp */
  469. oo=sysfiletree(rfile,'yow')
  470. comments.filestamp=strip(upper(yow.1))
  471.  
  472.  
  473. if wow=0 then return 0
  474.  
  475. return nj
  476.  
  477.  
  478. /* ------------- Reset the cache: --------------------- */
  479. /*     Save current cache to a backup recordall file, delete current
  480.      cache file, and rewrite minimal (just wildcards and comments)
  481.      set
  482. */
  483.  
  484. reset_cache:procedure expose comments. wilds. simples. verbose
  485. parse arg rfile,maxlines
  486.  
  487. /* but update if external changes occured  (might obviate need to shrink cache) */
  488. isold=cache_unsync(rfile,comments.filestamp)
  489. if isold=1 then do
  490.      nrecs=open_record_cache(rfile)
  491.      if verbose>0 then call pmprintf(' External change, reread RECORD_ALL_FILE into cache ')
  492.      return nrecs
  493. end
  494.  
  495. rfile2=rfile
  496. /* rename recordallfile to record.nnn (nnn=01 .. 999) */
  497. foofoo=lastpos('.',rfile)
  498. if foofoo>0 then
  499.    rfile2=delstr(rfile,foofoo)
  500.  
  501. useme=' '
  502. do mm=1 to 999
  503.    if stream(rfile2||'.'||mm,'c','query exists')=' ' then do
  504.        useme=rfile2||'.'||mm
  505.        leave
  506.    end
  507. end
  508. if useme=' ' then useme=dostempname(rfile2||'.???') /* should never happen ..*/
  509. foo=dosrename(rfile,useme)
  510. if foo=0 then return 0
  511. if verbose>0 then call pmprintf('RECORD_ALL_FILE too big; reset (old file renamed to '||useme)
  512.  
  513. if wilds.0+comments.0> maxlines then do
  514.    if verbose>0 then call pmprintf(" Warning: truncating comments in (RECORD_ALL_FILE) " rfile)
  515.    comments.0=trunc(maxlines/2)
  516. end
  517.  
  518. /* reset counts */
  519. simples.0=0
  520. do mm=1 to wilds.0
  521.    wilds.mm.qct=0
  522. end
  523.  
  524. nrec=write_cache(rfile,1)
  525. if verbose>0 then call pmprintf(" Write RECORD_ALL_FILE cache: " nrec)
  526.  
  527. return wilds.0
  528.  
  529.  
  530.  
  531.  
  532.  
  533. /* --------------------- update cache ---------*/
  534. /* match an entry to existing cache -- augment the match
  535. or add a new entry */
  536.  
  537. update_cache:procedure expose wilds. simples. verbose
  538.  
  539. parse arg doit
  540.  
  541. /* fix up doit */
  542. doit=translate(strip(doit),'/','\')
  543. doit=strip(doit,'l','/')
  544.  
  545. nsimples=simples.0
  546. do mm=1 to nsimples
  547.    if upper(simples.mm.qname)=upper(doit) then do
  548.         simples.mm.qct=simples.mm.qct+1
  549.         simples.mm.qmess=date('o')
  550.         return 1
  551.    end
  552. end
  553.  
  554.  
  555. nwilds=wilds.0
  556. asterat=0 ; afterstar=0 ; gotit=0
  557. do mm=1 to nwilds
  558.     ares=sref_wildcard(upper(doit),upper(wilds.mm.qname),0)
  559.     parse var ares astat "," aurl ;  astat=strip(astat)
  560.     if astat=0 then iterate   /* no match */
  561.  
  562.    foo1=pos('*',wilds.mm.qname)
  563.    if foo1 >= asterat then do
  564.        tmp1=length(wilds.mm.qname)-foo1
  565.        if foo1>asterat | tmp1>afteraster then  do
  566.           asterat=foo1 ; afteraster=tmp1
  567.           gotit=mm
  568.        end              /* either condition */
  569.     end
  570. end
  571.  
  572. if gotit>0 then do
  573.     wilds.gotit.qct=wilds.gotit.qct+1
  574.     wilds.gotit.qmess=date('O')
  575.     return 1
  576. end
  577.  
  578.  
  579. nsimples=nsimples+1 ;simples.0=nsimples
  580. simples.nsimples.qname=doit
  581. simples.nsimples.qct=1
  582. simples.nsimples.qmess=date('o')
  583.  
  584.  
  585. return 1
  586.  
  587.  
  588. /* ------------- save the cache: --------------------- */
  589. /*     Save current cache to recordall file, rename current
  590.       file to .bak
  591. */
  592.  
  593. save_cache:procedure expose comments. wilds. simples. verbose
  594. parse arg rfile
  595.  
  596.  
  597. /* but update if external changes occured  */
  598. isold=cache_unsync(rfile,comments.filestamp)
  599. if isold=1 then do
  600.      nrecs=open_record_cache(rfile)
  601.      if verbose>0 then call pmprintf(' RECORD_ALL_FILE changed, did not write cache (reread RECORD_ALL_FILE instead ')
  602.      return nrecs
  603. end
  604.  
  605.  
  606.  
  607. rfile2=rfile
  608. /* rename recordallfile to record.nnn (nnn=01 .. 999) */
  609. foofoo=lastpos('.',rfile)
  610. if foofoo>0 then
  611.    rfile2=delstr(rfile,foofoo)
  612. useme=rfile2||'.bak'
  613. a=sysfiledelete(useme)
  614. a=dosrename(rfile,useme)
  615. if verbose>1 then  call pmprintf(' Writing current RECORD_ALL_FILE cache ')
  616.  
  617. nrec=write_cache(rfile,0)
  618.  
  619. return nrec
  620.  
  621.  
  622. /* --- return 1 if filestamp has changed */
  623. cache_unsync:procedure expose verbose
  624. parse arg record_all_file,thestamp
  625.  
  626. /* get file stamp */
  627.  
  628. oo=sysfiletree(record_all_file,'yow')
  629. afilestamp=strip(upper(yow.1))
  630.  
  631. if afilestamp=thestamp then return 0
  632. return 1
  633.  
  634.  
  635. /* -------- get julian date/time of file ----*/
  636. file_jul_date:procedure
  637. parse arg afile
  638.  
  639. how0=dosfileinfo(afile,'W')
  640. parse var how0 how hh ':' mm ':' ss
  641. nsec=((hh*60*60) + (mm*60) + ss)/(24*60*60)
  642. ndays=dateconv(how,'U','B')
  643. return ndays+nsec
  644.  
  645.  
  646. /***************************/
  647. /* check for log suppression condition */
  648. is_logok:procedure expose stuff.
  649. parse upper arg sel1,doorig,clientname0,record_status,write_logs,user
  650.  
  651.  
  652. if sel1=-1 then do
  653.     aa=stuff.!noreferer
  654.     if aa=' ' then return 1
  655. end
  656. else do
  657.     if write_logs=0 then return 0
  658.  /* check status */
  659.     aa=stuff.!nocodes
  660.    if wordpos(strip(record_status),aa)>0 then return 0
  661.  
  662. /* check clientname */
  663.  
  664.     aa=stuff.!nouser
  665. /* is it a direct match to the "user" */
  666.     if wordpos(upper(user),aa)>0 then return 0
  667. end
  668.  
  669. /* nope, so now check ip addresses  (possibly noreferer) */
  670. c1=translate(clientname0,' ','.')
  671. do ll=1 to words(aa)
  672.    aa1=upper(strip(word(aa,ll)))  /* for each entry in the nouser list */
  673.    if clientname0=aa1 then return 0       /* exact match */
  674.    if user=aa1 then return 0       /* exact match */
  675.  
  676.    if pos('*',aa1)>0 then do     /* possible wild card match */
  677.         aa1=translate(aa1,' ','.')
  678.         if words(aa1) <> words(c1) then iterate /* can't be a match */
  679.         die=1
  680.         do ll2=1 to words(c1)
  681.              c1q=strip(word(c1,ll2)) ; aa1q=strip(word(aa1,ll2))
  682.              if aa1q='*' then iterate
  683.              if c1q=aa1q then iterate
  684.              die=0 ; leave              /* if here, segment did not match */
  685.         end /* do */
  686.         if die=1 then return 0  /* all segments matched */
  687.    end  /* Do wildcard  */
  688. end /* do */
  689.  
  690. if sel=-1 then return 1         /* noreferer did NOT match */
  691.  
  692. /* check urls */
  693. theurl=strip(sel1)
  694. if doorig=1 then theurl=' '
  695. ido=stuff.!nourl.0
  696. starat=0 ; afterstar=0
  697.  
  698. do mm=1 to ido
  699.     aurl0=stuff.!nourl.mm
  700.     ares=sref_wildcard(theurl,aurl0,0)
  701.     parse var ares astat  .
  702.     astat=strip(astat)
  703.     if astat=0 then iterate   /* no match */
  704.     return 0  /* match, so it's dead */
  705. end
  706. return 1
  707.  
  708.  
  709.  
  710. /***************************/
  711. /* read sreflogs.ini file, return stuff in stuff. */
  712. get_sreflogs:procedure expose stuff. workdir verbose
  713. parse arg afl
  714. /* possible varialbes */
  715.   varlist="COMMONLOG BROWSERLOG REFERERLOG NOOPTIONS NOHTTP NOCODES NOUSER NOURL NOREFERER "
  716.   stemlist="COMMONLOG BROWSERLOG REFERERLOG NOURL "
  717.  
  718. /* default values */
  719.  stuff.!nooptions=0 ; stuff.!nohttp=0
  720.  stuff.!nourl.0=0 ; stuff.!noreferer=' '
  721.  stuff.!nocodes=' ' ; stuff.!nouser=' '
  722.  stuff.!commonlog=workdir||'\COMMON.LOG'
  723.  stuff.!browserlog=workdir||'\BROWSER.LOG'
  724.  stuff.!refererlog=workdir||'\REFEFER.LOG'
  725.  stuff.!list='COMMONLOG BROWSERLOG REFERERLOG '
  726.  stuff.!stamp=' '
  727.  
  728. /* look in sreflogs.ini for info */
  729. afl=workdir||'\SREFLOGS.INI'
  730. foo=fileread(afl,logsl,,'E')
  731. if logsl.0=0 then return 1       /* use the defaults */
  732.  
  733.  
  734. stuff.!stamp=sysfiletree(afl,'FOO','f')
  735. STUFF.!STAMP=FOO.1
  736.  
  737.  
  738. do mm=1 to logsl.0
  739.    aline=strip(upper(logsl.mm))
  740.    if aline="" | abbrev(aline,';')=1 then iterate
  741.    parse upper var aline avar '=' aval
  742.    aval=strip(translate(aval,' ','"'||"'"))
  743.    avar0=strip(avar)
  744.    avar=translate(avar0,' ','.')
  745.    avar1=strip(word(avar,1))
  746.    if words(avar)=1 then do      /* check the 1 word opts */
  747.       if wordpos(avar1,varlist)=0 then iterate  /* not a valid variable */
  748.       if wordpos(avar1,'COMMONLOG BROWSERLOG REFERERLOG')>0 then do /* check validity */
  749.           aval=chk_file(workdir,aval)
  750.       end
  751.  
  752.       exx='!'||avar1
  753.       stuff.exx=aval
  754.  
  755.       iterate
  756.    end
  757. /* else, one of the stem boys */
  758.  
  759.   if wordpos(avar1,stemlist)=0 then iterate  /* not valid stem var */
  760.   select
  761.        when avar1="NOURL" then do
  762.           inq=stuff.!nourl.0+1
  763.           if pos('?',aval)>0 then do
  764.                parse var aval a1 '?' a2
  765.                a1=strip(translate(a1,'/','\'),'l','/')
  766.                aval=a1||'?'||a2
  767.           end
  768.           else do
  769.              aval=strip(translate(aval,'/','\'),'l','/')
  770.           end
  771.           stuff.!nourl.inq=aval
  772.           stuff.!nourl.0=inq
  773.         end
  774.         otherwise  do      /* check for allowables */
  775.             useme=chk_file(workdir,aval)
  776.             if useme=0 then iterate
  777.             exx=avar1||'.!'||word(avar,2)
  778.             if words(avar)>2 then exx=exx||'.!'||word(avar,3)
  779.              exx2='!'||exx
  780.             stuff.exx2=useme
  781.             stuff.!list=stuff.!list||' '||exx
  782.         end             /*otherwise */
  783.   end                /* select */
  784.  
  785. end          /* logsl */
  786.  
  787. if verbose >2 then call pmprintf(' SRE-Filter Post-Filter Thread: Log file list:loglist 'stuff.!list)
  788. return 1
  789.  
  790. /************/
  791. /* check for valid file name, and return it. Return 0 if no good */
  792. chk_file:procedure
  793. parse arg workdir, aval
  794.  
  795.   fn1=translate(strip(upper(aval)),'\','/')  /* the filename */
  796.  
  797.   fn1=strip(translate(fn1,' ',"'"||'"'))
  798.   if abbrev(fn1,'\')=1 | pos(':',fn1)>0 then
  799.        fuse=fn1
  800.    else
  801.        fuse=workdir||'\'||fn1
  802.    foo=strip(filespec('d',fuse)||filespec('p',fuse),'t','\')
  803.    if right(foo,1)=':' then foo=foo||'\'
  804.  
  805.    if dosisdir(foo)=0 then return 0  /* no such dir--error, so ignore */
  806.  
  807.    return fuse
  808.  
  809.  
  810.  
  811. /***************/
  812. /* write to the log files */
  813. write_clog:procedure expose clog.
  814. parse arg ttime,ltime,lbig
  815.  
  816. if clog.0=0 then return 0
  817.  
  818. /* are they all to the same file? */
  819. bname=clog.1.!file
  820. idid=1
  821. do mm=2 to clog.0
  822.       if clog.mm.!file<>bname then leave
  823.       idid=mm
  824. end
  825. if idid=clog.0  then do  /* all same name, dump the bunch */
  826.  
  827.    if bname=0 then return 0 /* all suppressed */
  828.     do nn=1 to clog.0
  829.        tt.nn=clog.nn
  830.     end
  831.     tt.0=clog.0
  832.     foo=filewrite(bname,tt,'A')
  833.     cfoo=jeepers(bname,lbig)
  834. end
  835. else do         /* several files (multi host system */
  836.   tt.0=1
  837.   do nn=1 to clog.0
  838.     if clog.nn.!file=0 then iterate
  839.     tt.1=clog.nn
  840.     foo=filewrite(clog.nn.!file,tt,'A')
  841.     foo=jeepers(clog.nn.!file,lbig)
  842.  end
  843. end
  844.  
  845. return 1
  846.  
  847. /********/
  848. /* is log file too big (check every 4th time? */
  849. jeepers:procedure
  850. parse arg bname0,toob
  851.  
  852. if toob=0 then return 1
  853. foo1=random(1,5)
  854. if foo1<5 then return 0   /* every 5th write */
  855.  
  856. foo=sysfiletree(bname0,'boo','F')
  857.  
  858. if boo.0>0 then do
  859.   ih=strip(word(boo.1,3))
  860.   if ih>(1000*toob) then do
  861.       call pmprintf(' ')
  862.       call pmprintf(' ******             WARNING                  ****** ')
  863.       call pmprintf(' Your log file ('bname0') is becoming large ('ih)
  864.       call pmprintf(' ******             WARNING                  ****** ')
  865.       call pmprintf(' ')
  866.  
  867.   end
  868. end
  869. return 0
  870.  
  871.  
  872.  
  873. /***************/
  874. /* this is sort of a stupid algorithim, but it's probably adequate
  875. (given rexx's problems with passing stem variables */
  876.  
  877. /* write to the common log files */
  878. write_blog:procedure expose blog.
  879.  
  880. if blog.0=0 then return 0
  881.  
  882. /* are they all to the same file? */
  883. bname=blog.1.!file
  884. idid=1
  885. do mm=2 to blog.0
  886.       if blog.mm.!file<>bname then leave
  887.       idid=mm
  888. end
  889. if idid=blog.0  then do  /* all same name, dump the bunch */
  890.    if bname=0 then return 0 /* all suppressed */
  891.     do nn=1 to blog.0
  892.        tt.nn=blog.nn
  893.     end
  894.     tt.0=blog.0
  895.     foo=filewrite(bname,tt,'A')
  896. end
  897. else do         /* several files (multi host system */
  898.   tt.0=1
  899.   do nn=1 to blog.0
  900.     if blog.nn.!file=0 then iterate
  901.     tt.1=blog.nn
  902.     foo=filewrite(blog.nn.!file,tt,'A')
  903.  end
  904. end
  905. return 1
  906.  
  907.  
  908. /***************/
  909. /* write to the refeerer log files */
  910. write_rlog:procedure expose rlog.
  911.  
  912. if rlog.0=0 then return 0
  913.  
  914. /* are they all to the same file? */
  915. bname=rlog.1.!file
  916. idid=1
  917. do mm=2 to rlog.0
  918.       if rlog.mm.!file<>bname then leave
  919.       idid=mm
  920. end
  921. if idid=rlog.0  then do  /* all same name, dump the bunch */
  922.    if bname=0 then return 0 /* all suppressed */
  923.     do nn=1 to rlog.0
  924.        tt.nn=rlog.nn
  925.     end
  926.     tt.0=rlog.0
  927.     foo=filewrite(bname,tt,'A')
  928. end
  929. else do         /* several files (multi host system */
  930.   tt.0=1
  931.   do nn=1 to rlog.0
  932.     if rlog.nn.!file=0 then iterate
  933.     tt.1=rlog.nn
  934.     foo=filewrite(rlog.nn.!file,tt,'A')
  935.  end
  936. end
  937. return 1
  938.  
  939. /************/
  940. /* which log file to use */
  941. which_logs:procedure expose stuff.
  942. parse arg sport,hname,dalog
  943. if hname<>' ' then do
  944.   alist=dalog||'.!'||hname||'.!'||sport
  945.   alist=alist||' '||dalog||'.!'||hname||' '||dalog
  946. end
  947. else do
  948.     alist=dalog||'.!'||sport||' '||dalog
  949. end
  950. alist=upper(alist)
  951. do li=1 to words(alist)
  952.    a1=strip(word(alist,li))
  953.    if wordpos(a1,stuff.!list)>0 then do
  954.        axe='!'||a1
  955.        return stuff.axe
  956.     end
  957. end
  958. return 0
  959.  
  960.